home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Browsers, Managers & Extensions / Mozilla Weave 0.2.7 / latest-weave.xpi / chrome / sync.jar / content / notification.xml < prev    next >
Extensible Markup Language  |  2008-07-31  |  13KB  |  308 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!DOCTYPE bindings [
  4. <!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
  5. %notificationDTD;
  6. <!ENTITY % weaveNotificationDTD SYSTEM "chrome://weave/locale/notification.dtd">
  7. %weaveNotificationDTD;
  8. ]>
  9.  
  10. <bindings id="notificationBindings"
  11.           xmlns="http://www.mozilla.org/xbl"
  12.           xmlns:xbl="http://www.mozilla.org/xbl"
  13.           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  14.  
  15.   <binding id="notificationbox" extends="chrome://global/content/bindings/notification.xml#notificationbox">
  16.     <content>
  17.       <xul:vbox xbl:inherits="hidden=notificationshidden">
  18.         <xul:spacer/>
  19.         <children includes="notification"/>
  20.       </xul:vbox>
  21.       <children/>
  22.     </content>
  23.  
  24.     <implementation>
  25.  
  26. <!-- FIXME: instantiate this._log for all objects -->
  27.  
  28.       <constructor><![CDATA[
  29.         const Cc = Components.classes;
  30.         const Ci = Components.interfaces;
  31.         const Cr = Components.results;
  32.         const Cu = Components.utils;
  33.  
  34.         Cu.import("resource://weave/Observers.js");
  35.         Cu.import("resource://weave/notifications.js");
  36.         Cu.import("resource://weave/service.js");
  37.  
  38.         // Register the notification box as an observer of notification changes.
  39.         // FIXME: make Observers accept an object, pass it "this", then
  40.         // implement "observe" in this object and make it call
  41.         // onNotificationAdded and onNotificationRemoved instead of using these
  42.         // helper functions, so we can remove the observer on destruction.
  43.         var self = this;
  44.         Observers.add(function(s, t, d) { self.onNotificationAdded(s, t, d) },
  45.                       "weave:notification:added");
  46.         Observers.add(function(s, t, d) { self.onNotificationRemoved(s, t, d) },
  47.                       "weave:notification:removed");
  48.  
  49.         for each (var notification in Notifications.notifications)
  50.           this._appendNotification(notification);
  51.       ]]></constructor>
  52.  
  53.       <destructor><![CDATA[
  54.         //Observers.remove(this.onNotificationAdded, "weave:notification:added");
  55.         //Observers.remove(this.onNotificationRemoved, "weave:notification:removed");
  56.       ]]></destructor>
  57.  
  58.       <method name="onNotificationAdded">
  59.         <parameter name="subject"/>
  60.         <parameter name="topic"/>
  61.         <parameter name="data"/>
  62.         <body><![CDATA[
  63.           this._appendNotification(subject);
  64.         ]]></body>
  65.       </method>
  66.  
  67.       <method name="onNotificationRemoved">
  68.         <parameter name="subject"/>
  69.         <parameter name="topic"/>
  70.         <parameter name="data"/>
  71.         <body><![CDATA[
  72.           // If the view of the notification hasn't been removed yet, remove it.
  73.           var notifications = this.allNotifications;
  74.           for each (var notification in notifications) {
  75.             if (notification == subject) {
  76.               notification.close();
  77.               break;
  78.             }
  79.           }
  80.  
  81.           // If the user has just closed the last notification, close the panel.
  82.           // FIXME: this is not quite right, because it might not have been
  83.           // the user that caused weave:notification:removed to get called.
  84.           // We need to differentiate between "notification removed" and "user
  85.           // closed the notification" and only close the panel if it was
  86.           // the user who closed the last notification.  Maybe we should make
  87.           // the notification's close method handle closing the panel,
  88.           // but should the notification box or its notifications really know
  89.           // they are located inside the panel?
  90.           var panel = document.getElementById("sync-notifications-panel");
  91.           if (panel.state == "open" && Notifications.notifications.length == 0)
  92.             panel.hidePopup();
  93.  
  94.         ]]></body>
  95.       </method>
  96.  
  97.       <method name="_appendNotification">
  98.         <parameter name="notification"/>
  99.         <body><![CDATA[
  100.           var node = this.appendNotification(notification.title,
  101.                                              notification.description,
  102.                                              notification.iconURL,
  103.                                              notification.priority,
  104.                                              notification.buttons);
  105.           node.className = notification.constructor.name;
  106.           node.notification = notification;
  107.         ]]></body>
  108.       </method>
  109.  
  110.     </implementation>
  111.   </binding>
  112.  
  113.   <binding id="notification" extends="chrome://global/content/bindings/notification.xml#notification">
  114.     <content>
  115.       <xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type" align="start">
  116.         <xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image" style="padding: 3px;"/>
  117.         <xul:vbox flex="1">
  118.           <xul:hbox anonid="details" align="center" flex="1">
  119.             <xul:description anonid="messageText" class="messageText" flex="1" xbl:inherits="xbl:text=label"/>
  120.             <xul:spacer flex="1"/>
  121.           </xul:hbox>
  122.           <xul:description xbl:inherits="xbl:text=value"/>
  123.  
  124.           <!-- The children are the buttons defined by the notification. -->
  125.           <xul:hbox oncommand="document.getBindingParent(this)._doButtonCommand(event);">
  126.             <xul:spacer flex="1"/>
  127.             <children/>
  128.           </xul:hbox>
  129.  
  130.         </xul:vbox>
  131.         <xul:spacer flex="1"/>
  132.         <xul:toolbarbutton ondblclick="event.stopPropagation();"
  133.                            class="messageCloseButton tabbable"
  134.                            xbl:inherits="hidden=hideclose"
  135.                            tooltiptext="&closeNotification.tooltip;"
  136.                            oncommand="document.getBindingParent(this).close()"/>
  137.       </xul:hbox>
  138.     </content>
  139.     <implementation>
  140.       <!-- Note: this used to be a field, but for some reason it kept getting
  141.          - reset to its default value for TabNotification elements.
  142.          - As a property, that doesn't happen, even though the property stores
  143.          - its value in a JS property |_notification| that is not defined
  144.          - in XBL as a field or property.  Maybe this is wrong, but it works.
  145.          -->
  146.       <property name="notification"
  147.                 onget="return this._notification"
  148.                 onset="this._notification = val; return val;"/>
  149.       <method name="close">
  150.         <body><![CDATA[
  151.           Notifications.remove(this.notification);
  152.  
  153.           // We should be able to call the base class's close method here
  154.           // to remove the notification element from the notification box,
  155.           // but we can't because of bug 373652, so instead we copied its code
  156.           // and execute it below.
  157.           var control = this.control;
  158.           if (control)
  159.             control.removeNotification(this);
  160.           else
  161.             this.hidden = true;
  162.         ]]></body>
  163.       </method>
  164.     </implementation>
  165.   </binding>
  166.  
  167.   <binding id="TabsNotification" extends="chrome://weave/content/notification.xml#notification">
  168.     <content>
  169.       <xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type" align="start">
  170.         <xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image"/>
  171.         <xul:vbox flex="1">
  172.           <xul:hbox anonid="details" align="center" flex="1">
  173.             <xul:description anonid="messageText" class="messageText" flex="1">
  174.               &syncTabsPanel.title;
  175.             </xul:description>
  176.             <xul:spacer flex="1"/>
  177.           </xul:hbox>
  178.           <xul:description>
  179.             &syncTabsPanel.description;
  180.           </xul:description>
  181.           <xul:listbox anonid="sync-tabs-list"/>
  182.           <xul:hbox>
  183.             <xul:spacer flex="1"/>
  184.             <xul:button label="&syncTabsButton.label;"
  185.                         oncommand="document.getBindingParent(this)._doSyncTabs();
  186.                                    document.getBindingParent(this).close();"/>
  187.             <children/>
  188.           </xul:hbox>
  189.         </xul:vbox>
  190.         <xul:toolbarbutton class="messageCloseButton tabbable"
  191.                            xbl:inherits="hidden=hideclose"
  192.                            tooltiptext="&closeNotification.tooltip;"
  193.                            ondblclick="event.stopPropagation();"
  194.                            oncommand="document.getBindingParent(this).close()"/>
  195.       </xul:hbox>
  196.     </content>
  197.     <implementation>
  198.       <constructor>
  199.         this._initTabsPanel();
  200.       </constructor>
  201.  
  202.       <field name="_sessionStore" readonly="true">
  203.         Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
  204.       </field>
  205.  
  206.       <field name="_json" readonly="true">
  207.         Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
  208.       </field>
  209.  
  210.       <!-- FIXME: refactor this function with the identical one in sync.js. -->
  211.       <method name="_getVirtualTabs">
  212.         <body><![CDATA[
  213.           var virtualTabs = Weave.Engines.get("tabs").virtualTabs;
  214.  
  215.           // Convert the hash of virtual tabs indexed by ID into an array
  216.           // of virtual tabs whose ID is stored in an ID property.
  217.           virtualTabs = [tab for each (tab in virtualTabs)];
  218.           for (var i = 0; i < virtualTabs.length; i++)
  219.             virtualTabs[i].id = i;
  220.       
  221.           // Sort virtual tabs by their position in their windows.
  222.           // Note: we don't actually group by window first, so all first tabs
  223.           // will appear first in the list, followed by all second tabs, and so on.
  224.           // FIXME: group by window, even though we aren't opening them up that way,
  225.           // so the list better resembles the pattern the user remembers.
  226.           virtualTabs.sort(function(a, b) a.position > b.position ?  1 :
  227.                                           a.position < b.position ? -1 : 0);
  228.       
  229.           return virtualTabs;
  230.         ]]></body>
  231.       </method>
  232.  
  233.       <method name="_initTabsPanel">
  234.         <body><![CDATA[
  235.           var list = document.getAnonymousElementByAttribute(this, "anonid",
  236.                                                              "sync-tabs-list");
  237.           var virtualTabs = this._getVirtualTabs();
  238.       
  239.           // Remove virtual tabs that have previously been disposed of by the user.
  240.           //virtualTabs = virtualTabs.filter(function(v) !v._disposed);
  241.       
  242.           while (list.hasChildNodes())
  243.             list.removeChild(list.lastChild);
  244.       
  245.           var numItems = 0;
  246.           for each (var virtualTab in virtualTabs) {
  247.             var currentEntry = virtualTab.state.entries[virtualTab.state.index - 1];
  248.             if (!currentEntry)
  249.               continue;
  250.             var label = currentEntry.title ? currentEntry.title : currentEntry.url;
  251.             var listitem = list.appendItem(label, virtualTab.id);
  252.             listitem.label = label;
  253.             listitem.value = virtualTab.id;
  254.             listitem.setAttribute("type", "checkbox");
  255.             // Make a tooltip that contains either or both of the title and URL.
  256.             listitem.tooltipText =
  257.               [currentEntry.title, currentEntry.url].filter(function(v) v).join("\n");
  258.  
  259.             ++numItems;
  260.           }
  261.  
  262.           // Resize the list to the number of items (up to ten).  We should
  263.           // be able to set this via CSS |height: auto; max-height: something|,
  264.           // but that doesn't work (the list is slightly shorter than it needs
  265.           // to be and keeps resizing, perhaps from bug 413336 and/or 261411).
  266.           list.setAttribute("rows", numItems > 10 ? 10 : numItems);
  267.         ]]></body>
  268.       </method>
  269.  
  270.       <method name="_doSyncTabs">
  271.         <body><![CDATA[
  272.           var list = document.getAnonymousElementByAttribute(this, "anonid",
  273.                                                              "sync-tabs-list");
  274.           var virtualTabs = this._getVirtualTabs();
  275.  
  276.           for (var i = 0; i < list.childNodes.length; i++) {
  277.             var listitem = list.childNodes[i];
  278.             var virtualTab = virtualTabs[listitem.value];
  279.             if (!virtualTab) {
  280.               // FIXME: warn about the virtual tab having gone away.
  281.               // FIXME: figure out why virtual tabs sometimes go away
  282.               // and what to do about it.
  283.               continue;
  284.             }
  285.             if (listitem.checked) {
  286.               var tab = gBrowser.addTab("about:blank");
  287.               this._sessionStore.setTabState(tab, this._json.encode(virtualTab.state));
  288.               delete virtualTabs[listitem.value];
  289.             }
  290.             else {
  291.               // Mark the tab disposed of by the user so we don't show it the next
  292.               // time the user opens the sync tabs panel.  Note: this flag does not
  293.               // get synced to the server, so disposal happens on each client
  294.               // separately, which means the user will still be prompted about this
  295.               // tab when syncing to a third client.
  296.               virtualTab._disposed = true;
  297.             }
  298.           }
  299.  
  300.           //Weave.Engines.get("tabs").store.virtualTabs = virtualTabs;
  301.         ]]></body>
  302.       </method>
  303.  
  304.     </implementation>
  305.   </binding>
  306.  
  307. </bindings>
  308.